package com.aloudmeta.grpc.support.metric;

import com.aloudmeta.grpc.service.DubboEchoService;
import io.grpc.MethodDescriptor;
import io.grpc.ServiceDescriptor;
import io.micrometer.core.instrument.MeterRegistry;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.actuate.info.InfoContributor;
import org.springframework.boot.actuate.info.SimpleInfoContributor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.*;

import static com.aloudmeta.grpc.util.GrpcUtils.extractMethodName;

/**
 * huaixin 2022/2/9 2:48 PM
 */
@Configuration
public class GrpcServerMetricConfiguration {

    @Autowired
    private MeterRegistry simpleMeterRegistry;

    @Bean
    InfoContributor grpcInfoContributor(DubboEchoService grpcService) {
        final Map<String, Object> details = new LinkedHashMap<>();
        details.put("port", 50051);

        final Map<String, List<String>> services = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
        details.put("services", services);
        final ServiceDescriptor serviceDescriptor = grpcService.bindService().getServiceDescriptor();

        final List<String> methods = collectMethodNamesForService(serviceDescriptor);
        services.put(serviceDescriptor.getName(), methods);

        return new SimpleInfoContributor("grpc.server", details);
    }

    /**
     * Gets all method names from the given service descriptor.
     *
     * @param serviceDescriptor The service descriptor to get the names from.
     * @return The newly created and sorted list of the method names.
     */
    protected List<String> collectMethodNamesForService(final ServiceDescriptor serviceDescriptor) {
        final List<String> methods = new ArrayList<>();
        for (final MethodDescriptor<?, ?> grpcMethod : serviceDescriptor.getMethods()) {
            methods.add(extractMethodName(grpcMethod));
        }
        methods.sort(String.CASE_INSENSITIVE_ORDER);
        return methods;
    }
}
